
Namespace std
    Public Class pair(Of firstType, secondType)
        Implements IComparable(Of pair(Of firstType, secondType)), IComparable, ICloneable

        Public first As firstType
        Public second As secondType

        Public Sub New()
            first = Nothing
            second = Nothing
        End Sub

        Private Function compareToImpl(ByVal thatfirst As firstType, ByVal thatsecond As secondType) As Int32
            Dim cmp As Int32
            cmp = compare(first, thatfirst)
            If cmp = 0 Then
                Return compare(second, thatsecond)
            Else
                Return cmp
            End If
        End Function

        Public Function CompareTo(ByVal other As pair(Of firstType, secondType)) As Int32 _
                                                    Implements IComparable(Of pair(Of firstType, secondType)).CompareTo
            If other Is Nothing Then
                Return compareToImpl(CType(Nothing, firstType), CType(Nothing, secondType))
            Else
                Return compareToImpl(other.first, other.second)
            End If
        End Function

        Public Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
            Return CompareTo(convertor.cast(Of pair(Of firstType, secondType))(obj, False))
        End Function

        Public Shared Operator =(ByVal this As pair(Of firstType, secondType), ByVal that As Object) As Boolean
            Return operatorEqual(this, that)
        End Operator

        Public Shared Operator <>(ByVal this As pair(Of firstType, secondType), ByVal that As Object) As Boolean
            Return operatorUnequal(this, that)
        End Operator

        Public Shared Operator =(ByVal this As pair(Of firstType, secondType), _
                                 ByVal that As pair(Of firstType, secondType)) As Boolean
            Return operatorEqual(this, that)
        End Operator

        Public Shared Operator <>(ByVal this As pair(Of firstType, secondType), _
                                  ByVal that As pair(Of firstType, secondType)) As Boolean
            Return operatorUnequal(this, that)
        End Operator

        Public Overridable Function Clone() As Object Implements System.ICloneable.Clone
            If Me Is Nothing Then
                Return Nothing
            Else
                Dim rtn As pair(Of firstType, secondType) = Nothing
                rtn = alloc(Me)
                copy(rtn.first, first)
                copy(rtn.second, second)
                Return rtn
            End If
        End Function

        Public Shared Function make_pair(ByVal first As firstType, ByVal second As secondType) _
                                        As pair(Of firstType, secondType)
            Dim rtn As pair(Of firstType, secondType)
            rtn = New pair(Of firstType, secondType)()
            copy(rtn.first, first)
            copy(rtn.second, second)
            Return rtn
        End Function

        Public Overrides Function ToString() As String
            Return Convert.ToString(first) + ", " + Convert.ToString(second)
        End Function

        Public Overrides Function GetHashCode() As Integer
            Dim rtn As Int64
            If Not first Is Nothing Then
                rtn = first.GetHashCode()
            End If
            If Not second Is Nothing Then
                rtn += second.GetHashCode()
            End If

            Return (rtn Mod maxInt32)
        End Function

        Public Overrides Function Equals(ByVal obj As Object) As Boolean
            Return operatorEqual(Me, obj)
        End Function
    End Class

    Public Module pair
        Public Function make_pair(Of firstT, secondT)(ByVal first As firstT, ByVal second As secondT) _
                                                                                            As pair(Of firstT, secondT)
            Return pair(Of firstT, secondT).make_pair(first, second)
        End Function
    End Module
End Namespace
